//中间件，解析格式是否符合,统一错误处理
const {UserService} = require("../service/user.service");
const {userFormatError, userAlreadyExisted, tryCatchError, tokenExpiredError, userNotAlreadyExisted, loginError,
    pwdInvalidError
} = require("../enum/err.type.enum");
const bcrypt = require('bcryptjs')
const jwt = require("jsonwebtoken");
const {SECRET} = require("../config/config");
const {JsonWebTokenError} = require("jsonwebtoken");
// 判空
const userValidator = async (ctx, next)=>{
    let {userName, userPwd} = ctx.request.body
    if(!userName || !userPwd){
        console.error('-----LOG-------','用户名或密码为空', ctx.request.body)
        ctx.app.emit('error',userFormatError,ctx)
        return
    }
    await next()
}
// 验证用户
const verifyUser = async (ctx,next)=>{
    let {userName } = ctx.request.body
    try{
        if(await UserService.getUserInfo({userName})){
            console.error('-----LOG-------','用户名已经存在',{userName})
            ctx.app.emit('error',userAlreadyExisted,ctx)
            return
        }
    }catch (err){
        ctx.app.emit('error',tryCatchError,ctx)
        return
    }
    await next()

}

//加密
const cryptPassword = async (ctx,next) =>{
    let {userPwd} = ctx.request.body
    if(typeof userPwd !=='string'){
        userPwd +=''
    }
    const salt = bcrypt.genSaltSync(10)
    // 密文
    ctx.request.body.userPwd = bcrypt.hashSync(userPwd, salt)
    await next()
}
const verifyLogin = async (ctx,next) =>{
    let {userName, userPwd} = ctx.request.body
    if(typeof userPwd !=='string'){
        userPwd +=''
    }
    try {
        const res = await UserService.getUserInfo({userName})
        if(!res){
            ctx.app.emit('error',userNotAlreadyExisted,ctx)
            return
        }
        if(!bcrypt.compareSync(userPwd, res.userPwd)){
            ctx.app.emit('error',pwdInvalidError,ctx)
            return
        }
    } catch (e) {
        console.error(e)
        return ctx.app.emit('error', tryCatchError,ctx)
    }
    await next()
}
// 验证
const auth = async (ctx,next)=>{
    let token = ctx.header.authorization
    token = token.replace('Bearer ','')
    try{
        ctx.state.user = jwt.verify(token, SECRET)
    }catch(err) {
       switch (err.name){
           case 'TokenExpiredError':
               console.error('token过期',err)
               return ctx.app.emit('error',tokenExpiredError,ctx)
           case 'JsonWebTokenError':
               console.error('无效token',err)
               return ctx.app.emit('error',JsonWebTokenError,ctx)
       }
        return
    }
    await next()
}
module.exports = {
    userValidator,
    verifyUser,
    cryptPassword,
    auth,
    verifyLogin
}
